package com.link.gateway.core.cllog;


import com.link.gateway.core.kafka.KafkaTemplateFacotry;
import com.link.gateway.core.kafka.conf.KafkaEnv;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.text.SimpleDateFormat;
import java.util.concurrent.ExecutionException;

public class LogMessageBuilder {
    private static final Logger logger = LogManager.getLogger(LogMessageBuilder.class);
    private static final String SEPARATOR = "^";
    private static final SimpleDateFormat DF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
    private static final String IP = LCLogger.getIp();



    /**
     * SimpleDateFormat线程不安全，加锁
     */
    private static String formatDate(Long currentTimeMillis) {
        synchronized (DF) {
            return DF.format(currentTimeMillis);
        }
    }

    private Long id;
    private String level;
    private String className;
    private String messageKey;
    private StringBuilder message = new StringBuilder();

    LogMessageBuilder(String level, String className, Long id) {
        this.level = level;
        this.className = className;
        this.id = id;
    }

    public LogMessageBuilder withMessageKey(String messageKey) {
        this.messageKey = messageKey;
        return this;
    }

    public LogMessageBuilder withMessage(String message) {
        this.message.append(mergeLines(message));
        return this;
    }

    public void flush() {
        //将日志信息输出到日志文件中
        if ("error".equals(this.level)) {
            logger.error("className:" + this.className + "\tmessageKey:" + this.messageKey + "\tmessage:" + this.message.toString());
        } else if ("warn".equals(this.level)) {
            logger.warn("className:" + this.className + "\tmessageKey:" + this.messageKey + "\tmessage:" + this.message.toString());
        } else {
            logger.info("className:" + this.className + "\tmessageKey:" + this.messageKey + "\tmessage:" + this.message.toString());
        }

        try {
            KafkaTemplateFacotry.send(KafkaTemplateFacotry.LOG_TOPIC, messageStream());
        } catch (ExecutionException e) {
            logger.error("发送日志失败" + e.getMessage());
        }
    }

    private String mergeLines(String value) {
        return value.replaceAll("\\\n", ";;;").replaceAll("=", ".eq.").replaceAll("\\|\\|", "\\\t");
    }

    private String messageStream() {
        String userIdAndName = LCLogger.getUserIdAndName();
        // 时间^主机Ip^级别^线程ID^ClassName^MessageKey^Message^Stack^Traces
        return formatDate(System.currentTimeMillis()) + SEPARATOR
                + handleNull(IP) + SEPARATOR
                + this.level + SEPARATOR
                + this.id + SEPARATOR
                + handleNull(this.className) + SEPARATOR
                + handleNull(this.messageKey) + SEPARATOR
                + handleNull(this.message.toString()) + SEPARATOR
                + "--" + SEPARATOR
                + "--" + SEPARATOR
                + handleNull(KafkaEnv.getProfile()) + SEPARATOR
                + userIdAndName;
    }

    public static boolean isNull(String str) {
        if (null == str || "".equals(str)) {
            return true;
        }
        return false;
    }

    public static String handleNull(String str) {
        if (isNull(str)) {
            return "--";
        }
        return str;
    }

}
